package com.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dao.EquipDAO;
import com.dao.SignUpDAO;
import com.dao.UserDAO;
import com.model._do.AppointmentDO;
import com.model._do.EquipmentDO;
import com.model._do.SignUpDO;
import com.model._do.UserDO;
import com.model.dto.EquipAppointDTO;
import com.model.dto.SignedRelateDTO;
import com.model.dto.SuperviseDTO.EquipSignDTO;
import com.model.dto.SuperviseDTO.Search.EquipSearch;
import com.model.dto.SuperviseDTO.SignRelateDTO;
import com.service.AppointmentService;
import com.service.EquipmentService;
import com.util.LocationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Repository("equipmentService")
public class EquipmentServiceImpl implements EquipmentService {

    @Autowired
    private EquipDAO equipDAO;

    @Autowired
    private SignUpDAO signUpDAO;

    @Autowired
    private AppointmentService appointmentService;

    @Autowired
    private UserDAO userDAO;

    @Override
    public EquipmentDO getEquipByEquipId(String equipId) {
        return equipDAO.getEquipmentByEquipId(equipId);
    }

    @Override
    public List<EquipmentDO> getNearEquip(HashMap<String, String> hashMap) {
        return equipDAO.selectNearEquip(hashMap);
    }

    @Override
    public List<EquipmentDO> signedWithMeDoctor(UserDO user) {
        return equipDAO.signedWithMeDoctor(user);
    }

    @Override
    public void doUpdateEquipInfo(EquipmentDO equipment) {
        if(!StringUtils.isEmpty(equipment.getEquipUserName())){
            equipDAO.doUpdateName(equipment);
        }
        if(!StringUtils.isEmpty(equipment.getEquipUserIdentify())){
            equipDAO.doUpdateId(equipment);
        }
        if(!StringUtils.isEmpty(equipment.getEquipUserLocation())){
            equipDAO.doUpdateLocation(equipment);
        }
        if(!StringUtils.isEmpty(equipment.getEquipUserSex())){
            equipDAO.doUpdateSex(equipment);
        }
    }

    @Override
    public List<EquipmentDO> getSignedWithMe(SignUpDO sign) {
        List<SignUpDO> signList = signUpDAO.getByUserId(sign);
        return signList.stream().map(this::trunToDTO).collect(Collectors.toList());
    }

    @Override
    public List<SignRelateDTO> getSupervise(SignUpDO sign){
        List<SignUpDO> signList = signUpDAO.getByUserId(sign);
        List<SignRelateDTO> relateList = new ArrayList<>();
        for (SignUpDO s: signList
             ) {
            SignRelateDTO relate = new SignRelateDTO();
            relate.setSign(s);
            relate.setEquip(this.trunToDTO(s));
            relateList.add(relate);
        }
        return relateList;
    }

    @Override
    public List<EquipAppointDTO> getEquipDoctorRelate(SignUpDO sign) {
        List<SignUpDO> signList = signUpDAO.getByUserId(sign);
        List<EquipmentDO> equipmentList = signList.stream().map(this::mapToEquip).filter(Objects::nonNull).collect(Collectors.toList());
        return equipmentList.stream().map(this::getRelate).filter(Objects::nonNull).collect(Collectors.toList());
    }

    @Override
    public String addNewEquip(SignUpDO sign) {
        SignUpDO already = signUpDAO.getIfRelateExist(sign);
        if(already != null){
            return "关联关系已存在";
        }
        EquipmentDO search = new EquipmentDO();
        search.setEquipId(sign.getEquipId());
        search = equipDAO.getEquipmentByEquipId(search.getEquipId());
        if(search == null){
            return "设备id为空";
        }
        signUpDAO.addNewEquip(sign);
        return "success";
    }

    @Override
    public List<EquipmentDO> getSignUnConfirmDoctor(SignUpDO sign) {
        //获得了与医生相关的未完成签约
        List<SignUpDO> signList = signUpDAO.getByUserId(sign);

        //所有doctorConfirm为空的满足条件
        return signList.stream().filter(s -> StringUtils.isEmpty(s.getDoctorConfirm())).map(this::trunToDTO).collect(Collectors.toList());
     }

    @Override
    public List<EquipmentDO> getSignUnConfirmPatient(SignUpDO sign) {
        //获得与equip相关的未完成签约
        List<SignUpDO> signList = signUpDAO.getSignedByEquipId(sign.getEquipId());

        //所有patientConfirm为空的满足条件
        return signList.stream().filter(s -> StringUtils.isEmpty(s.getPatientConfirm())).map(this::trunToDTO).collect(Collectors.toList());
    }

    @Override
    public List<EquipSignDTO> getEquipInfo(EquipSearch search) {
        List<EquipmentDO> equipList = equipDAO.equipSearch(search);
        List<EquipSignDTO> newList = new ArrayList<>();
        for (EquipmentDO equip: equipList
             ) {
            EquipSignDTO info = new EquipSignDTO();
            boolean result = LocationUtil.filterLocation(JSONObject.parseObject(equip.getEquipUserLocation()), search);
            if(result){

            } else {
                continue;
            }
            info.setEquip(equip);
            List<SignUpDO> signList = signUpDAO.getSignSupervise(equip.getEquipId());
            List<SignRelateDTO> userList = new ArrayList<>();
            for (SignUpDO temp: signList
                 ) {
                SignRelateDTO relate = new SignRelateDTO();
                UserDO user = userDAO.getUserByUserId(temp.getUserId());
                relate.setUser(user);
                relate.setSign(temp);
                userList.add(relate);
            }
            info.setUserList(userList);
            newList.add(info);
        }
        return newList;
    }

    private EquipmentDO mapToEquip(SignUpDO sign){
        return equipDAO.getEquipmentByEquipId(sign.getEquipId());
    }

    private EquipAppointDTO getRelate(EquipmentDO equipment){
        EquipAppointDTO relate = new EquipAppointDTO();
        relate.setEquipment(equipment);
        List<AppointmentDO> appointmentList = appointmentService.getAppointByEntityId(equipment);
        appointmentList.sort(Comparator.comparing(AppointmentDO::getAppointmentTime));
        if(appointmentList.size() <= 0){
            return null;
        }
        relate.setAppointList(appointmentList);
        return relate;
    }

    private EquipmentDO trunToDTO(SignUpDO sign){
        String equipId = sign.getEquipId();
        EquipmentDO equipmentDO = new EquipmentDO();
        equipmentDO.setEquipId(equipId);
        equipmentDO = equipDAO.getEquipmentByEquipId(equipmentDO.getEquipId());
        return equipmentDO;
    }
}
